from django.http import JsonResponse
from django.views.generic import View
from django_redis import get_redis_connection
from django.shortcuts import render
from utils.mixin import LoginRequiredMixin

from apps.goods.models import GoodsSKU


# Create your views here.
# /cart/add
# 采用ajax post 请求
class CartAddView(View):
    """购物车记录添加"""

    def post(self, request):
        """购物车记录添加"""
        user = request.user
        if not user.is_authenticated():
            # 用户未登录
            return JsonResponse({'res': 0, 'errmsg': '请登录'})
        # 接收数据
        sku_id = request.POST.get('sku_id')
        count = request.POST.get('count')
        # 数据的校验
        if not all([sku_id, count]):
            return JsonResponse({'res': 1, 'errmsg': '数据不完整'})

        # 校验添加的商品数量
        try:
            count = int(count)
        except Exception as e:
            # 数目出错
            return JsonResponse({'res': 2, 'errmsg': '商品数目出错'})

        # 检验商品是否存在
        try:
            sku = GoodsSKU.objects.get(id=sku_id)
        except GoodsSKU.DoesNotExist:
            # 商品不存在
            return JsonResponse({'res': 3, 'errmsg': '商品不存在'})

        # 业务处理:购物车记录添加
        conn = get_redis_connection('default')
        cart_key = 'cart_%d' % user.id
        # 先尝试获取sku_id hget cart_key
        # 如果sku_id在hash中不存在,hget返回None
        cart_count = conn.hget(cart_key, sku_id)
        # cart_count不为None
        if cart_count:
            # 累加购物车中的商品的数目(redis拿出来的都是字符串)
            count += int(cart_count)
        # 校验商品的库存
        if count > sku.stock:
            return JsonResponse({'res': 4, 'errmsg': '商品库存不足'})
        # 设置hash中sku_id的值,如果sku_id不存在就是添加,存在就是更新
        conn.hset(cart_key, sku_id, count)

        # 计算用户购物车中商品的条目数
        total_count = conn.hlen(cart_key)

        # 返回应答
        return JsonResponse({'res': 5, 'total_count': total_count, 'message': '添加成功'})


# 查看购物车信息
class CartInfoView(LoginRequiredMixin, View):
    """购物车消息"""

    def get(self, request):
        """显示"""
        # 获取登录的用户
        user = request.user
        # 获取用户购物车中的商品信息
        conn = get_redis_connection('default')
        cart_key = 'cart_%d' % user.id
        # {'商品id':商品数量}
        cart_dict = conn.hgetall(cart_key)

        # 遍历获取商品的信息
        sku_list = []
        total_count = 0
        total_amount = 0
        for sku_id, count in cart_dict.items():
            # 根据商品的id获取商品的信息
            sku = GoodsSKU.objects.get(id=sku_id)
            # 计算商品的小计
            amount = sku.price * int(count)
            # 动态给sku对象增加一个属性amout,保存商品
            sku.amount = amount
            # 动态给sku对象增加一个属性count
            sku.count = count
            sku_list.append(sku)
            # 累加计算总件数和总价格
            total_count += int(count)
            total_amount += amount

        # 组织上下文
        content = {'sku_list': sku_list, 'total_count': total_count, 'total_amount': total_amount}

        return render(request, 'cart.html', content)


# 更新购物车商品数量的记录
# 采用ajax post 请求
# 前端需要传递的产生 sku_id ,count
class CartUpdateView(View):
    """更新购物车商品数量的记录"""

    def post(self, request):
        """购物车更新"""
        user = request.user
        if not user.is_authenticated():
            # 用户未登录
            return JsonResponse({'res': 0, 'errmsg': '请登录'})
        # 接收数据
        sku_id = request.POST.get('sku_id')
        count = request.POST.get('count')
        # 数据的校验
        if not all([sku_id, count]):
            return JsonResponse({'res': 1, 'errmsg': '数据不完整'})

        # 校验添加的商品数量
        try:
            count = int(count)
        except Exception as e:
            # 数目出错
            return JsonResponse({'res': 2, 'errmsg': '商品数目出错'})

        # 检验商品是否存在
        try:
            sku = GoodsSKU.objects.get(id=sku_id)
        except GoodsSKU.DoesNotExist:
            # 商品不存在
            return JsonResponse({'res': 3, 'errmsg': '商品不存在'})

        # 业务处理: 更新购物车
        conn = get_redis_connection('default')
        cart_key = 'cart_%d' % user.id
        # 校验商品的库存
        if count > sku.stock:
            return JsonResponse({'res': 4, 'errmsg': '商品库存不足'})
        # 更新 设置hash中sku_id的值,如果sku_id不存在就是添加,存在就是更新
        conn.hset(cart_key, sku_id, count)

        # 计算改用户商品的总件数
        total_count = 0
        vals = conn.hvals(cart_key)
        for val in vals:
            total_count += int(val)

        # 返回应答
        return JsonResponse({'res': 5, 'mesage': '更新成功', 'total_count': total_count})


# 采用ajax post 请求
class CartDeleteView(View):
    """删除购物车中的商品记录"""

    def post(self, request):
        """删除购物车中的商品记录"""
        user = request.user
        if not user.is_authenticated():
            # 用户未登录
            return JsonResponse({'res': 0, 'errmsg': '请登录'})
        # 获取参数
        sku_id = request.POST.get('sku_id')

        # 参数校验
        if not all([sku_id, ]):
            return JsonResponse({'res': 1, 'errmsg': '无效的商品id'})

        # 检验商品是否存在
        try:
            sku = GoodsSKU.objects.get(id=sku_id)
        except GoodsSKU.DoesNotExist:
            # 商品不存在
            return JsonResponse({'res': 2, 'errmsg': '商品不存在'})

        # 业务代码: 删除购物车中的商品记录
        conn = get_redis_connection('default')
        cart_key = 'cart_%d' % user.id
        # 删除
        conn.hdel(cart_key, sku_id)

        # 计算改用户商品的总件数
        total_count = 0
        vals = conn.hvals(cart_key)
        for val in vals:
            total_count += int(val)

        # 返回应答
        return JsonResponse({'res': 3, 'total_count': total_count, 'message': '商品删除'})
